package com.aiyi.server.manager.nginx.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.aiyi.server.manager.nginx.beam.NginxServer;
import com.aiyi.server.manager.nginx.bean.Bucket;
import com.aiyi.server.manager.nginx.bean.TableDate;
import com.aiyi.server.manager.nginx.bean.nginx.NginxLocation;
import com.aiyi.server.manager.nginx.common.NginxUtils;
import com.aiyi.server.manager.nginx.conf.Configer;
import com.aiyi.server.manager.nginx.service.NginxService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.ValidationException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 存储空间管理
 */
@Controller
@RequestMapping("admin/bucket")
public class BucketController {

	@Autowired
	private NginxService nginxService;

	/**
	 * 去bucket列表界面
	 *
	 * @return : String
	 * @Description :
	 * @Creation Date : 2018年2月27日 下午4:46:20
	 * @Author : 郭胜凯
	 */
	@RequestMapping("list")
	public String listLisner(Model model) {
		return "admin/bucket/list/index";
	}

	/**
	 * 获得监听列表借口
	 *
	 * @return : TableDate
	 * @Description :
	 * @Creation Date : 2018年2月27日 下午6:31:45
	 * @Author : 郭胜凯
	 */
	@RequestMapping(value = "list/list")
	@ResponseBody
	public TableDate getLiskerList() {
		TableDate date = new TableDate();
		date.setList(getAllBucket());
		return date;
	}

	/**
	 * 编辑页面
	 *
	 * @return : String
	 * @Description :
	 * @Creation Date : 2018年2月28日 上午10:47:29
	 * @Author : 郭胜凯
	 */
	@RequestMapping(value = "list/{bucket}/edit")
	public String edit(@PathVariable String bucket, Model model) {
		Bucket bucketNew = new Bucket();
		List<NginxLocation> nginxLocations = nginxService.listRules(NginxUtils.read(), null, null, null);
		if (!"null".equals(bucket)) {
			bucketNew.setName(bucket);
			bucketNew.setLocation(getLocationName(nginxLocations, bucket));
		}
		List<NginxServer> nginxServers = nginxService.listLisner(NginxUtils.read());
		model.addAttribute("nginxServers", nginxServers);
		model.addAttribute("bucket", bucketNew);
		return "admin/bucket/list/edit";
	}

	/**
	 * 上传页面
	 *
	 * @return : String
	 * @Description :
	 * @Creation Date : 2018年2月28日 上午10:47:29
	 * @Author : 郭胜凯
	 */
	@RequestMapping(value = "upload/page")
	public String edit(String bucket, String uploadPath, Model model) {
		model.addAttribute("bucket", bucket);
		model.addAttribute("uploadPath", uploadPath);
		return "admin/bucket/list/up";
	}

	/**
	 * 获取所有的bucket
	 *
	 * @return
	 */
	public List<Bucket> getAllBucket() {
		List<Bucket> list = new ArrayList<>();
		String bucketPath = Configer.getNginxBucketPath();
		List<NginxLocation> nginxLocations = nginxService.listRules(NginxUtils.read(), null, null, null);
		File file = new File(bucketPath);
		// 遍历bucket文件夹返回
		if (file.exists() && file.isDirectory()) {
			File[] files = file.listFiles();
			for (File subBucket : files) {
				if (subBucket.exists() && subBucket.isDirectory()) {
					Bucket bucket = new Bucket();
					bucket.setName(subBucket.getName());
					bucket.setPath(subBucket.getAbsolutePath().replace("\\", File.separator));
					bucket.setLocation(getLocationName(nginxLocations, subBucket.getName()));
					list.add(bucket);
				}
			}
		}
		return list;
	}

	private String getLocationName(List<NginxLocation> nginxLocations, String bucket) {
		String location = nginxLocations.stream().filter(n -> n.getPath().replace("/", "").equals(bucket)).map(n -> n.getServer()).collect(Collectors.joining());
		return location;
	}

	/**
	 * 保存bucket配置
	 *
	 * @return
	 */
	@RequestMapping(value = "list/{bucket}/edit", method = RequestMethod.PUT)
	@ResponseBody
	public String save(@PathVariable String bucket, @RequestBody Map<String, Object> names) throws FileNotFoundException {
		String newName = (String) names.get("name");
		String oldName = (String) names.get("oldName");
		String oldLocation = (String) names.get("server");
		NginxLocation nginxLocation = new NginxLocation();
		nginxLocation.setServer(oldLocation);
		String rule = "/";
		if ("null".equals(bucket)) {
			String newFilePath = Configer.getNginxBucketPath() + File.separator + newName;
			File file = new File(newFilePath);
			//新增
			if (file.exists()) {
				throw new ValidationException("已有相同名称的bucket");
			}
			file.mkdir();
		} else {
			//修改
			rule = rule + oldName;
			oldLocation = oldLocation.replace(":", "_");
			String newFilePath = Configer.getNginxBucketPath() + File.separator + newName;
			String oldFilePath = Configer.getNginxBucketPath() + File.separator + oldName;
			File file = new File(oldFilePath);
			file.renameTo(new File(newFilePath));
		}
		nginxLocation.setPath("/" + newName);
		nginxLocation.setRoot(Configer.getNginxBucketPath().replace("\\", File.separator));
		nginxLocation.setName("bucket应用");
		nginxLocation.setProxyPass("");
		nginxService.saveRule(oldLocation, rule, nginxLocation);

		return "SUCCESS";
	}


	@RequestMapping(value = "list/{bucket}/edit/{location}", method = RequestMethod.DELETE)
	@ResponseBody
	public String delete(@PathVariable String bucket, @PathVariable("location") String location) {
		String bucketPath = Configer.getNginxBucketPath() + File.separator + bucket;
		FileUtil.del(bucketPath);
		nginxService.delRule(location, File.separator + bucket);
		return "SUCCESS";
	}

	@RequestMapping(value = "view/{bucket}", method = RequestMethod.GET)
	@ResponseBody
	public List<String> view(@PathVariable String bucket) {
		String bucketPath = Configer.getNginxBucketPath() + File.separator + bucket;
		File file = new File(bucketPath);
		List<String> filePath = new ArrayList<>();
		listFile(file, filePath);
		List<NginxLocation> nginxLocations = nginxService.listRules(NginxUtils.read(), null, null, null);
		String locationName = getLocationName(nginxLocations, bucket);
		String http = "http://";
		if (locationName.contains("443")) {
			http = "https://";
		}
		locationName = http + locationName;
		StringBuilder httpBuild = new StringBuilder(locationName);
		filePath = filePath.stream().map(path -> {
			int first = path.indexOf("bucket");
			path = httpBuild.toString() + path.substring(first + 6, path.length());
			return path;
		}).collect(Collectors.toList());
		return filePath;
	}

	@RequestMapping(value = "del/{bucket}", method = RequestMethod.DELETE)
	@ResponseBody
	public String del(@RequestBody String path, @PathVariable String bucket) {
		int first = path.indexOf(bucket);
		String filePath = Configer.getNginxBucketPath()+path.substring(first-1,path.length()-1);
		FileUtil.del(filePath);
		return "SUCCESS";
	}


	/**
	 * 扫描所有文件
	 *
	 * @param file
	 * @param list
	 */
	private void listFile(File file, List<String> list) {
		File[] files = file.listFiles();
		for (File file1 : files) {
			if (file1.isDirectory()) {
				listFile(file1, list);
			} else {
				list.add(file1.getAbsolutePath());
			}
		}
	}


	/**
	 * 上传文件到bucket
	 *
	 * @return
	 */
	@RequestMapping(value = "upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
	@ResponseBody
	public Map<String, Object> save(String uploadPath, MultipartFile file) {
		String originalFilename = file.getOriginalFilename();
		try {
			if (originalFilename.contains("zip")) {
				ZipUtil.unzip(file.getInputStream(), new File(uploadPath), Charset.defaultCharset());
			} else {
				FileUtil.writeFromStream(file.getInputStream(), uploadPath + File.separator + file.getOriginalFilename());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		Map<String, Object> res = new HashMap<>();
		res.put("code", 0);
		res.put("msg", "上传ok");
		return res;
	}
}
